package edu.hawaii.kukui

import edu.hawaii.kukui.KukuiUser
import edu.hawaii.kukui.KukuiRole



/**
 * User controller.
 */
class KukuiUserController {

  def authenticateService

  // the delete, save and update actions only accept POST requests
  static Map allowedMethods = [delete: 'POST', save: 'POST', update: 'POST']

  def index = {
    redirect action: list, params: params
  }

  def list = {
    if (!params.max) {
      params.max = 10
    }
    [personList: KukuiUser.list(params)]
  }

  def show = {
    def person = KukuiUser.get(params.id)
    if (!person) {
      flash.message = "KukuiUser not found with id $params.id"
      redirect action: list
      return
    }
    List roleNames = []
    for (role in person.authorities) {
      roleNames << role.authority
    }
    roleNames.sort {n1, n2 ->
      n1 <=> n2
    }
    [person: person, roleNames: roleNames]
  }

  /**
   * Person delete action. Before removing an existing person,
   * he should be removed from those authorities which he is involved.
   */
  def delete = {

    def person = KukuiUser.get(params.id)
    if (person) {
      def authPrincipal = authenticateService.principal()
      //avoid self-delete if the logged-in user is an admin
      if (!(authPrincipal instanceof String) && authPrincipal.username == person.username) {
        flash.message = "You can not delete yourself, please login as another admin and try again"
      }
      else {
        //first, delete this person from People_Authorities table.
        KukuiRole.findAll().each { it.removeFromPeople(person) }
        person.delete()
        flash.message = "KukuiUser $params.id deleted."
      }
    }
    else {
      flash.message = "KukuiUser not found with id $params.id"
    }

    redirect action: list
  }

  def edit = {

    def person = KukuiUser.get(params.id)
    if (!person) {
      flash.message = "KukuiUser not found with id $params.id"
      redirect action: list
      return
    }

    return buildPersonModel(person)
  }

  /**
   * Person update action.
   */
  def update = {

    def person = KukuiUser.get(params.id)
    if (!person) {
      flash.message = "KukuiUser not found with id $params.id"
      redirect action: edit, id: params.id
      return
    }

    long version = params.version.toLong()
    if (person.version > version) {
      person.errors.rejectValue 'version', "person.optimistic.locking.failure",
              "Another user has updated this KukuiUser while you were editing."
      render view: 'edit', model: buildPersonModel(person)
      return
    }

    def oldPassword = person.passwd
    person.properties = params
    if (!params.passwd.equals(oldPassword)) {
      person.passwd = authenticateService.encodePassword(params.passwd)
    }
    if (person.save()) {
      KukuiRole.findAll().each { it.removeFromPeople(person) }
      addRoles(person)
      redirect action: show, id: person.id
    }
    else {
      render view: 'edit', model: buildPersonModel(person)
    }
  }

  def create = {
    [person: new KukuiUser(params), authorityList: KukuiRole.list()]
  }

  /**
   * Person save action.
   */
  def save = {

    def person = new KukuiUser()
    person.properties = params
    person.passwd = authenticateService.encodePassword(params.passwd)
    if (person.save()) {
      addRoles(person)
      redirect action: show, id: person.id
    }
    else {
      render view: 'create', model: [authorityList: KukuiRole.list(), person: person]
    }
  }
  def user_image = {
    def pictureUser = KukuiUser.get(params.id)

    OutputStream out = response.getOutputStream();
    out.write(pictureUser.picture);
    out.close();
  }
  def image_r = {
    def i = KukuiUser.get(params.id)
    byte[] imagepic = i.picture
    //response.contentType = "image/jpeg"
    //response.setContentLength(i.picture.length)
    //response.outputStream.write(userImage.picture)
    //response.setHeader( "Content-Type", "image/png")    
    response.outputStream << imagepic
    //response.outputStream.flush()
  }

  private void addRoles(person) {
    for (String key in params.keySet()) {
      if (key.contains('ROLE') && 'on' == params.get(key)) {
        KukuiRole.findByAuthority(key).addToPeople(person)
      }
    }
  }

  private Map buildPersonModel(person) {

    List roles = KukuiRole.list()
    roles.sort {r1, r2 ->
      r1.authority <=> r2.authority
    }
    Set userRoleNames = []
    for (role in person.authorities) {
      userRoleNames << role.authority
    }
    LinkedHashMap<KukuiRole, Boolean> roleMap = [:]
    for (role in roles) {
      roleMap[(role)] = userRoleNames.contains(role.authority)
    }

    return [person: person, roleMap: roleMap]
  }
}
